Opensky

OpenSky provides api to get data for flights in progress. It is rate limited

Code
import requests
import pandas as pd
import geopandas
Code
def fetch_opensky_data():
    url = "https://opensky-network.org/api/states/all"
    response = requests.get(url)
    data = response.json()

    columns = [
        "icao24", "callsign", "origin_country", "time_position", "last_contact",
        "longitude", "latitude", "baro_altitude", "on_ground", "velocity",
        "heading", "vertical_rate", "sensors", "geo_altitude", "squawk",
        "spi", "position_source"
    ]

    df_raw = pd.DataFrame(data['states'], columns=columns)
    return (
        df_raw
        .assign(
            time_position=pd.to_datetime(df_raw["time_position"], unit="s"),
            last_contact=pd.to_datetime(df_raw["last_contact"], unit="s"),
        )
    )

df_flights = fetch_opensky_data()


df_flihts_non_nan = df_flights.dropna(subset=["longitude", "latitude"])
gdf = geopandas.GeoDataFrame(
    df_flihts_non_nan,
    geometry=geopandas.points_from_xy(df_flihts_non_nan.longitude, df_flihts_non_nan.latitude),
    crs="EPSG:4326",
)

gdf.explore(fullscreen=True, tooltip=False, popup=True)
Make this Notebook Trusted to load map: File -> Trust Notebook

Flights in world at notebook time

Number of flights by origin_country

Code
(
    df_flights
    .groupby("origin_country")
    .agg(num_flights=("icao24", "count"))
    .sort_values("num_flights", ascending=False)
    .head(20)
)
num_flights
origin_country
United States 1549
Australia 282
Germany 257
Ireland 253
China 245
Turkey 241
India 214
United Kingdom 180
Japan 162
France 158
Malta 155
Spain 150
Canada 146
Austria 142
Kingdom of the Netherlands 114
United Arab Emirates 110
Switzerland 97
Poland 87
Republic of Korea 73
Thailand 65

Top 20 countries with most flights

All flights

For reference

Code
df_flights
icao24 callsign origin_country time_position last_contact longitude latitude baro_altitude on_ground velocity heading vertical_rate sensors geo_altitude squawk spi position_source
0 39de4f TVF13AU France 2025-05-23 05:22:23 2025-05-23 05:22:24 15.2441 43.6133 11574.78 False 224.35 302.45 -0.65 None 11666.22 2053 False 0
1 801636 VTAQL India 2025-05-23 05:22:25 2025-05-23 05:22:25 72.2426 19.5978 5204.46 False 173.03 138.01 -4.88 None 5394.96 None False 0
2 39de4b TVF72TD France 2025-05-23 05:22:24 2025-05-23 05:22:25 12.1106 52.2264 8686.80 False 187.43 261.16 9.75 None 8496.30 1000 False 0
3 39de4a TVF46CN France 2025-05-23 05:22:24 2025-05-23 05:22:25 -2.8372 45.7037 11894.82 False 244.08 221.92 0.00 None 12047.22 7647 False 0
4 39de4c TVF30BT France 2025-05-23 05:22:25 2025-05-23 05:22:25 1.7482 46.7946 11277.60 False 239.05 192.30 0.00 None 11353.80 7653 False 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
5942 aa781f CKS220 United States 2025-05-23 05:22:22 2025-05-23 05:22:22 -152.8475 64.3178 10972.80 False 249.00 258.92 0.00 None 10805.16 5246 True 0
5943 a4359b UPS921 United States 2025-05-23 05:22:24 2025-05-23 05:22:24 -92.9572 38.3046 10675.62 False 273.22 88.92 0.00 None 10949.94 7252 False 0
5944 a0c7b3 ABX3114 United States 2025-05-23 05:22:25 2025-05-23 05:22:25 -81.9548 42.5158 11277.60 False 255.05 85.14 -0.33 None 11224.26 6264 False 0
5945 458664 CAT323 Denmark 2025-05-23 05:22:24 2025-05-23 05:22:25 10.7519 52.8907 11887.20 False 241.10 162.11 0.00 None 11757.66 3510 False 0
5946 458666 VKG1604 Denmark 2025-05-23 05:22:25 2025-05-23 05:22:25 10.6386 59.9969 5128.26 False 180.01 187.39 1.95 None 4945.38 4515 False 0

5947 rows × 17 columns